package org.test.device.architecture.utils;


import lombok.extern.slf4j.Slf4j;
import org.test.device.architecture.actions.Action;
import org.test.device.architecture.actions.ActionContext;
import org.test.device.architecture.actions.BaseAction;
import org.test.device.architecture.actions.BaseActionContext;
import org.test.device.architecture.exception.BusinessException;
import org.test.device.utils.BusinessCode;

/**
 * 〈〉<br>
 *
 * @author Mr.Wang
 * @create 2024/9/9
 */
@Slf4j
public final class ActionDispatcher {

    private static final String PKG_ACTION_CONTEXT = "actioncontext";
    private static final String PKG_ACTION = "action.";
    private static final String SUFFIX_ACTION = "Action";

    private ActionDispatcher() {
    }

    public static void execute(final BaseActionContext actionContext) throws BusinessException {
        final String actionName = actionContext.getClass().getSimpleName();
        final String packageName = actionContext.getClass().getPackage().getName();
        final String actionClassPath = getActionClass(actionName, packageName);
        try {
            final Class actionClass = Class.forName(actionClassPath);

            log.info("解析地址进行方法匹配......");
            final Action<ActionContext> action = (Action<ActionContext>) SpringContextHolder.getApplicationContext().getBean(actionClass);
            action.execute(actionContext);
        } catch (final ClassNotFoundException e) {
            log.info("地址解析出错！");
            throw new BusinessException("Cannot find class: " + actionClassPath, BusinessCode.SERVER_ERROR);
        }
    }

    /**
     * 拓展 方便快速的进入代码 和取消报名限制
     *
     * @param actionContext
     * @param actionClass
     */
    public static void execute(final BaseActionContext actionContext, Class<? extends BaseAction> actionClass) {
        final Action<ActionContext> action = SpringContextHolder.getApplicationContext().getBean(actionClass);
        action.execute(actionContext);
    }

    private static String getActionClass(final String actionName, final String packageName) {
        return packageName.replace(PKG_ACTION_CONTEXT, PKG_ACTION) + actionName + SUFFIX_ACTION;
    }
}